package org.tech4j.common.zip.lz4;

import net.jpountz.lz4.LZ4Compressor;
import net.jpountz.lz4.LZ4Factory;
import net.jpountz.lz4.LZ4FastDecompressor;
import org.apache.commons.lang3.ArrayUtils;
import org.tech4j.common.spi.Join;
import org.tech4j.common.zip.api.CompressData;
import org.tech4j.common.zip.api.CompressException;
import org.tech4j.common.zip.api.DecompressException;
import org.tech4j.common.zip.api.DefaultCompressData;
import org.tech4j.common.zip.api.ZipExecutor;

import java.nio.ByteBuffer;
import java.util.Objects;

/**
 * @program: tech4j-common
 * @description:
 * @author: YuKai Fan
 * @create: 2025/3/3 20:39
 **/
@Join
public class Lz4ZipExecutor implements ZipExecutor {

    private final LZ4Compressor compressor;
    private final LZ4FastDecompressor decompressor;

    public Lz4ZipExecutor() {
        LZ4Factory factory = LZ4Factory.fastestInstance();
        this.compressor = factory.fastCompressor();
        this.decompressor = factory.fastDecompressor();
    }

    @Override
    public int maxCompressedLength(int maxLength) {
        return this.compressor.maxCompressedLength(maxLength);
    }

    @Override
    public CompressData compress(byte[] data) {
        if (ArrayUtils.isEmpty(data)) {
            throw new CompressException("Prepare compressed data is empty");
        }
        byte[] compress = this.compressor.compress(data);
        return new DefaultCompressData(data.length, compress);
    }

    @Override
    public byte[] decompress(CompressData data) {
        if (Objects.isNull(data) || ArrayUtils.isEmpty(data.getCompressedData())) {
            throw new DecompressException("compressed data is empty");
        }
        return this.decompressor.decompress(data.getCompressedData(), data.getLength());
    }

    @Override
    public void compress(ByteBuffer input, ByteBuffer output) {
        this.compressor.compress(input, output);
    }

    @Override
    public void decompress(ByteBuffer input, ByteBuffer output) {
        this.decompressor.decompress(input, output);
    }
}
